package com.tte.common.thread;

import org.springframework.stereotype.Component;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * AsycThreadPool
 * @Author: DongWH
 * @Date: 2023/7/31 15:34
 */
@Component
public class AsycThreadPool {
    private volatile static ThreadPoolExecutor threadPoolExecutor;
    //线程池
    private volatile static AsycThreadPool threadPoolManager;

    static {
        threadPoolExecutor = new ThreadPoolExecutor(10,
                16, 60,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(1024), new ThreadPoolExecutor.CallerRunsPolicy());
    }

    //单例模式
    public static AsycThreadPool getInstance() {
        if (threadPoolManager == null) {
            synchronized (AsycThreadPool.class) {
                //同步锁 防止多线程出现多个实例
                if (threadPoolManager == null) {
                    threadPoolManager = new AsycThreadPool();
                }
            }
        }
        return threadPoolManager;
    }

    public void executeTask(Runnable task) {
        //从池子里面获得一个闲置的线程对象执行任务
        threadPoolExecutor.execute(task);
    }

    public static void main(String[] args) throws InterruptedException {
        AsycThreadPool asycThreadPool = new AsycThreadPool();
        asycThreadPool.executeTask(new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("任务执行开始");

                    System.out.println("正在执行任务");
                    Thread.sleep(10000);
                    System.out.println("任务执行结束");

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        //与shutdown()方法结合使用时，尤其要注意的是shutdown()方法必须要在awaitTermination()方法之前调用，该方法才会生效。否则会造成死锁。
        threadPoolExecutor.shutdown();
        //当使用awaitTermination时，主线程会处于一种等待的状态，等待线程池中所有的线程都运行完毕后才继续运行。
        threadPoolExecutor.awaitTermination(30,TimeUnit.MINUTES);
        System.out.println("所有的子线程都结束了！");
        System.out.println("执行结束");

        /*//或者调用shutdown方法后我们可以在一个死循环里面用isTerminated方法判断是否线程池中的所有线程已经执行完毕
        threadPoolExecutor.shutdown();
        while(true){
            System.out.println("结束了吗？");
            Thread.sleep(100);
            if(threadPoolExecutor.isTerminated()){
                System.out.println("都结束了！");
                break;
            }
        }*/
    }
}
